#include "QOSMeasurementRecord.h"

qosMeasurementRecord::qosMeasurementRecord(struct timeval const& startTime, RTPSource* src)
{
	fSource = src;
	fNext = NULL;
	kbits_per_second_min = 1e20;
	kbits_per_second_max = 0;
	kBytesTotal = 0.0;
	packet_loss_fraction_min = 1.0;
	packet_loss_fraction_max = 0.0;
	totNumPacketReceived = 0;
	totNumPacketExpected = 0;

	measurementEndTime = startTime;
	measurementStartTime = startTime;

	RTPReceptionStatsDB::Iterator statsIter(src->receptionStatsDB());
	RTPReceptionStats* stats = statsIter.next(true);

	if(stats != NULL)
	{
		kBytesTotal = stats->totNumKBytesReceived();
		totNumPacketReceived = stats->totNumPacketsReceived();
		totNumPacketExpected = stats->totNumPacketsExpected();
	}
}


qosMeasurementRecord::~qosMeasurementRecord()
{
	delete fNext;
}


void qosMeasurementRecord::periodicQOSMeasurement(const struct timeval& timeNow)
{
	unsigned int secsDiff = timeNow.tv_sec - measurementEndTime.tv_sec;
	int usecsDiff = timeNow.tv_usec - measurementEndTime.tv_usec;
	double timeDiff = secsDiff + usecsDiff/(1000000.0);
	measurementEndTime = timeNow;

	RTPReceptionStatsDB::Iterator statsIter(fSource->receptionStatsDB());
	RTPReceptionStats* stats = statsIter.next(true);

	if(stats != NULL)
	{
		double kBytesTotalNow = stats->totNumKBytesReceived();
		double kBytesDeltaNow = kBytesTotalNow - kBytesTotal;
		kBytesTotal = kBytesTotalNow;

		double kbpsNow = timeDiff == 0.0 ? 0.0 : 8*kBytesDeltaNow/timeDiff;
		if(kbpsNow < 0.0)
		{
			kbpsNow = 0.0;
		}
		else if(kbpsNow < kbits_per_second_min)
		{
			kbits_per_second_max = kbpsNow;
		}
		else if(kbpsNow > kbits_per_second_max)
		{
			kbits_per_second_max = kbpsNow;
		}

		unsigned int totReceivedNow = stats->totNumPacketsReceived();
		unsigned int totExpectedNow = stats->totNumPacketsExpected();

		unsigned int deltaReceivedNow = totReceivedNow - totNumPacketReceived;
		unsigned int deltaExpectedNow = totExpectedNow - totNumPacketExpected;

		totNumPacketReceived = totReceivedNow;
		totNumPacketExpected = totExpectedNow;

		double lossFractionNow = deltaExpectedNow == 0 ? 0.0 : 1.0 - deltaReceivedNow / (double)deltaExpectedNow;
		if(lossFractionNow < packet_loss_fraction_min)
		{
			packet_loss_fraction_min = lossFractionNow;
		}
		else if(lossFractionNow > packet_loss_fraction_max )
		{
			packet_loss_fraction_max = lossFractionNow;
		}
	}
}






